package zheezes.socket.impl.gbw;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import zheezes.protocol.Frame;
import zheezes.socket.Transput;


public class FrameSequence {
	public static final long MAX_TIMEOUT = 60 * 1000l; // just a minute
	
	private static Logger logger = Logger.getLogger(FrameSequence.class);
	
    private int no = 0;
    private boolean using = false;
    private Calendar aeadtime = Calendar.getInstance();
    private Transput mailbox = null;
    private int option = 0;
    private List<Frame> list = new ArrayList<Frame>();
    private boolean first = false;    private boolean last = false;
    
    public long defaultTimeout = 5 * 1000l;

    public FrameSequence(int no) {
        this.no = no;
    }

    public void addFrame(Frame frame) {
        list.add(frame);
    }

    public int getFrameNum() {
        return list.size();
    }
    
    private void check() {
		if (using) {
			if (Calendar.getInstance().after(aeadtime)) {
				logger.debug(String.format("%d aead time", no));
				using = false;
				mailbox = null;
				option = 0;
				list.clear();
				first = false;
				last = false;
			}
		}
	}

	/* you should use it in a minute, otherwise, system will retrieve it 
	 * when using this method, if some client's right was be retrieved, it will never get the message 
	 * */
	public synchronized int acquire() {
		check();
		if (!using) {
			using = true;
			aeadtime.add(Calendar.MILLISECOND, (int) 0);
			return 0;
		} else {
			return -1;
		}
	}
	
	public void release() {
		using = false;
	}
	
	/* to avoid some client hold it to much time */
    public void setAeadtime(Calendar aeadtime) {
    	if(aeadtime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis() <= MAX_TIMEOUT) {
            this.aeadtime = aeadtime;	
    	}
    }

	public void setTimeout(long timeout) {
		if (timeout < MAX_TIMEOUT) {
			aeadtime.add(Calendar.MILLISECOND, (int) timeout);
		}
	}

	public void setDefaultTimeout(long defaultTimeout) {
		if (defaultTimeout < MAX_TIMEOUT) {
			this.defaultTimeout = defaultTimeout;
		}
	}
    
    public int getNo() {
        return no;
    }

    public Calendar getAeadtime() {
        return aeadtime;
    }

    public Transput getMailbox() {
        return mailbox;
    }

    public int getOption() {
        return option;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public void setMailbox(Transput mailbox) {
        this.mailbox = mailbox;
    }

    public void setOption(int option) {
        this.option = option;
    }

    public boolean isFirst() {
        return first;
    }

    public boolean isLast() {
        return last;
    }

    public void setFirst(boolean first) {
        this.first = first;
    }

    public void setLast(boolean last) {
        this.last = last;
    }

	public long getDefaultTimeout() {
		return defaultTimeout;
	}
}
